<template>
    <div class="app-container">
        <div class="topbar-wrapper">
            <el-button link v-show="!customizing" @click="handleCustomize" icon="edit"
                style="margin-left: auto;">自定义布局</el-button>
            <el-button v-show="customizing" @click="handleCancelCustomize">取消</el-button>
            <el-button v-show="customizing" @click="handleSaveCustomize" icon="select">保存</el-button>
        </div>
        <div :class="['widgets-main', customizing ? 'customizing' : '']">
            <div class="widgets">
                <el-row :gutter="8">
                    <el-col v-for="(item, index) in layout" :key="index" :md="item.col" :xs="24">
                        <VueDraggable v-model="item.widgets" :animation="200" group="grid" handle=".customize-overlay"
                            class="draggable-box">
                            <div v-for="(item, idx2) in item.widgets" :key="idx2">
                                <div :class="['widgets-item', customizing ? 'customizing' : '']">
                                    <component :is="widgets[item]"></component>
                                    <div v-if="customizing" class="customize-overlay">
                                        <el-button class="close" link icon="remove" title="移除部件"
                                            @click="handleRemove(index, item)"></el-button>
                                        <label v-if="widgets[item]">
                                            <el-icon>
                                                <component :is="widgets[item].icon" />
                                            </el-icon>{{ widgets[item].title }}
                                        </label>
                                    </div>
                                </div>
                            </div>
                            <div class="hint-text" v-show="item.widgets.length <= 0 && customizing">
                                <el-text><el-icon>
                                        <Flag />
                                    </el-icon> 拖拽部件到此处</el-text>
                            </div>
                        </VueDraggable>
                    </el-col>
                </el-row>
            </div>
            <div class="widgets-aside" v-show="customizing">
                <!-- 推荐布局方案 -->
                <div class="hint">
                    <el-text>推荐方案</el-text>
                    <div class="hint-wrapper">
                        <div class="hint-item" v-for="(preset, index) in presetLayouts" :key="index">
                            <el-row :gutter="1" class="hint-layout"
                                :class="layout.map(f => f.col).join(',') === preset.layout.join(',') ? 'active' : ''"
                                @click="handleChooseLayout(index)">
                                <el-col :span="span" v-for="(span, index) in preset.layout">
                                    <span></span>
                                </el-col>
                            </el-row>
                            <el-text>{{ preset.name }}</el-text>
                        </div>
                    </div>
                </div>

                <!-- 可用部件 -->
                <div class="available-widgets">
                    <el-text>可用部件列表</el-text>
                    <el-row :gutter="20" class="available-wrappers">
                        <el-col class="available-wrapper" :span="24" :offset="0"
                            v-for="(widget, index) in availableWidgets" :key="index">
                            <div class="icon">
                                <component :is="widget[1].icon" style="display: inline-block;" />
                            </div>
                            <span>{{ widget[1].title }}</span>
                            <el-button type="primary" icon="plus" class="add" @click="handleAdd(widget[0])"></el-button>
                        </el-col>
                    </el-row>

                </div>
            </div>
        </div>

    </div>

</template>

<script setup>
import { ref } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import widgets from './widgets'

const { proxy } = getCurrentInstance()
const layoutKey = "dashboardLayout"
const customizing = ref(false);
// const availableWidgets = ref([]);
const availableWidgets = computed(() => {
    let usedWidgets = layout.value.flatMap(item => item.widgets);
    let available = Object.entries(widgets).filter(([item]) => !usedWidgets.includes(item));
    return available;
})

//当前布局方案
const presetLayouts = ref([{
    name: '方案一',
    layout: [12, 6, 6]
}, {
    name: '方案二',
    layout: [6, 6, 12, 24]
}, {
    name: '方案三',
    layout: [24, 24, 24]
}, {
    name: '方案四',
    layout: [6, 12, 6, 24]
}, {
    name: '方案五',
    layout: [8, 8, 8]
}, {
    name: '方案六',
    layout: [24, 12, 12, 24]
}])

//默认布局
const defaultLayout = [
    { col: 24, widgets: ["welcome"] },
    { col: 12, widgets: ["about"] },
    { col: 12, widgets: ["shortcut", "usageChart"] },
    { col: 24, widgets: [] }
];

const layout = ref([...defaultLayout]);


//触发自定义布局
const handleCustomize = () => {
    customizing.value = true;
}

//触发取消自定义布局
const handleCancelCustomize = () => {
    customizing.value = false;
    let cachedLayout = proxy.$cache.local.getJSON(layoutKey);
    layout.value = cachedLayout ? cachedLayout : defaultLayout;
}

//触发保存自定义布局
const handleSaveCustomize = () => {
    customizing.value = false;
    console.log(layout.value, "当前布局");
    proxy.$cache.local.setJSON(layoutKey, layout.value);
}

//选择布局方案
const handleChooseLayout = (index) => {
    const currentLayout = layout.value;
    const newCols = presetLayouts.value[index].layout;

    if (newCols.length === currentLayout.length) {
        // 列数相同，直接更新 col 值
        layout.value = currentLayout.map((item, i) => ({
            col: newCols[i],
            widgets: item.widgets
        }));
    } else {
        const allWidgets = currentLayout.flatMap(item => item.widgets);
        const widgetsPerCol = Math.floor(allWidgets.length / newCols.length);  // 基础每列的 widget 数量
        const remainder = allWidgets.length % newCols.length;  // 剩余 widgets 数量

        // 新布局列数调整，合理分配 widgets
        layout.value = newCols.map((col, i) => {
            const widgetsCount = widgetsPerCol + (i < remainder ? 1 : 0);  // 前 remainder 列多分配一个 widget
            const widgets = allWidgets.splice(0, widgetsCount);  // 获取当前列的 widgets
            return { col, widgets };
        });
    }
}

//移除组件
const handleRemove = (index, item) => {
    layout.value[index].widgets = layout.value[index].widgets.filter(i => item !== i);
}

const handleAdd = (name) => {
    // 找到 widgets 数组最少的那一列
    const minWidgetsIndex = layout.value.reduce((minIndex, currentItem, index) => {
        return currentItem.widgets.length < layout.value[minIndex].widgets.length ? index : minIndex;
    }, 0);
    // 将 name 推送到最少的那一列
    layout.value[minWidgetsIndex].widgets.push(name);
}

const getMatchedLayout = (customizedLayout) => {
    let grid = customizedLayout.map(item => item.col);
    for (let i = 0; i < presetLayouts.value.length; i++) {
        const layout = presetLayouts.value[i].layout;
        if (layout.length === grid.length && layout.every((value, index) => value === grid[index])) {
            return presetLayouts.value[i];
        }
    }
}

onBeforeMount(() => {
    let customizedLayout = proxy.$cache.local.getJSON(layoutKey);
    if (customizedLayout) {
        let matched = getMatchedLayout(customizedLayout);
        if (matched)
            layout.value = customizedLayout
    }
})


</script>

<style scoped lang="scss">
.app-container {
    padding-top: 0;
    position: absolute;
    height: 100%;
    width: 100%;
    overflow: hidden;
    flex-direction: column;
    display: flex;

    .widgets-main {
        display: flex;
        gap: 20px;
        flex: 1 auto;
        overflow: hidden;
        margin-right: -20px;
        padding-right: 20px;

        .widgets {
            flex: 1;
            transition: flex-grow .6s ease;
            overflow-x: hidden;
            overflow-y: auto;
            padding-right: 20px;
            /* 动画效果 */
        }

        .widgets-aside {
            flex-basis: 300px;
            height: 200px;
            /* transition: flex-grow .6s ease; */

            .hint-wrapper {
                display: flex;
                gap: 20px;
                flex-wrap: wrap;

                .hint-item {
                    text-align: center;

                    .hint-layout {
                        width: 60px;
                        height: 60px;
                        border: 1px solid var(--el-color-info-dark-2);
                        padding: 2px;
                        box-sizing: content-box;
                        cursor: pointer;

                        &.active {
                            span {
                                background-color: var(--el-color-primary-dark-2);
                            }
                        }

                        >div {
                            padding-bottom: 1px;
                        }

                        span {
                            background-color: var(--el-color-info-dark-2);
                            width: 100%;
                            height: 100%;
                            display: block;
                        }
                    }
                }
            }
        }

    }
}


.available-widgets {
    margin-top: 20px;

    .available-wrapper {
        display: flex;
        justify-content: space-between;
        margin-top: 20px;
        padding-bottom: 10px;
        padding-top: 10px;
        background-color: var(--el-color-info-light-8);
        align-items: center;
        gap: 10px;

        .icon {
            width: 20px;
            height: 20px;
        }

        .add {
            margin-left: auto;
        }
    }
}


.topbar-wrapper {
    display: flex;
    padding: 10px 0;
    justify-content: right;

    .editBtn {
        margin-left: auto;
    }
}

.draggable-box {
    height: 100%;
}

.customizing .widgets .el-col {
    margin-top: 8px;
}

.customizing .draggable-box {
    border: 1px dashed darkcyan;
    padding: 5px;

    .hint-text {
        height: 100%;
        min-height: 150px;
        display: flex;
        align-items: center;
        justify-content: center;
    }
}

.widgets .widgets-item {
    position: relative;
    margin-bottom: 15px;
}

.customize-overlay {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 999;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: var(--el-color-info-light-9);
    opacity: 0.9;
    cursor: move;
}

.customize-overlay label {
    background: var(--el-color-primary);
    color: #fff;
    height: 30px;
    padding: 0 15px;
    font-size: 12px;
    border-radius: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: move;
}

.customize-overlay label i {
    margin-right: 15px;
    font-size: 20px;
}

.customize-overlay .close {
    position: absolute;
    top: -2px;
    right: -2px;
    font-size: 20px;

}


.customize-overlay .close:hover {
    scale: 1.5;
    background: var(--el-button-hover-color);
}
</style>